package com.tc.nio.c4;

import com.tc.util.ByteBufferUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: tianchao
 * @Date: 2022/2/6 12:06
 * @Description:
 */
@Slf4j
public class NonBlockingServer {
    public static void main(String[] args) throws IOException {
        // 0
        ByteBuffer buffer = ByteBuffer.allocate(16);
        //1 创建服务器
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 非阻塞模式
        serverSocketChannel.configureBlocking(false);
        //2 绑定监听端口
        serverSocketChannel.bind(new InetSocketAddress(8080));
        // 3建立集合
        List<SocketChannel> channels = new ArrayList<>();
        while (true){
            // log.debug("connecting ....");
            // 4 accept 建立与客户端的通信 SocketChannel用来与客户端之间进行通讯
            // 非阻塞 针对accept方法，线程还会继续运行。如果没有建立连接 返回null;
            SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel != null){
                log.debug("connected .... sc: {}",socketChannel);
                //非阻塞 ，影响read方法
                socketChannel.configureBlocking(false);
                channels.add(socketChannel);
            }
            //channels.add(socketChannel);
            for (SocketChannel channel : channels) {
                // 5 接收客户端发送的数据
                //log.debug("before read...{}",channel);
                //socketChannel.configureBlocking(false); 意味着read方法也是非阻塞的
                //read读不到数据 会返回0
                int read = channel.read(buffer);
                if ( read > 0 ){
                    buffer.flip();
                    log.debug("after read...{}",channel);
                    ByteBufferUtil.debugRead(buffer);
                    buffer.clear();
                }
            }
        }
    }
}
